#ifndef RANSAC_H
#define RANSAC_H

#include <stdlib.h>
#include <math.h>
#include <vector>
#include <algorithm>
#include <numeric>
#include <functional>
#include <iterator>
#include <vector>

//#include <Point2d>
//#include <vector>
//#include <QFile>
//#include <QTime>

#include "opencv/cv.h"
//#include "opencv/cxtypes.h"

#include <iostream>
#include <cstdlib>


using namespace cv;
using namespace std;

extern int RandPointIndex_0;
extern int RandPointIndex_1;
class LinearModel
{
public:
    LinearModel() : mSlope(0), mIntercept(0) {};
    LinearModel(double _slope, double _intercept) : mSlope(_slope), mIntercept(_intercept) {};
    double mSlope;
    double mIntercept;
};

class CRansacLinear
{
public:

    vector<Point2d>  mObservationSet;
    vector<Point2d>  mBestConsensusSet;
    vector<Point2d>  mOutLiers;
    LinearModel     mBestModel;
    int             mRequiredInliers;
    int             mIterations;
    double           mBestError;
    double           mTreshold;
    Point2d  mA;
    Point2d  mB;
      

    CRansacLinear() 
    {
      mBestError=INT_MAX;
      RandPointIndex_0=INT_MAX;
      RandPointIndex_1=INT_MAX;
      //RNG rng( 0xFFFFFFFF );
      //rng.uniform(0,100);
    };




    void setObservationSet(const vector<Point2d>& observationSet) {
        //dump(observationSet);
        mObservationSet = observationSet;
    }


    void setModel(LinearModel& model) {
        mBestModel.mIntercept = model.mIntercept;
        mBestModel.mSlope     = model.mSlope;
    }

    void setTreshold(const float treshold) {
        mTreshold = treshold;
    }

    void setIterations(const int Iterations) {
        mIterations = Iterations;
    }

    void setRequiredInliers(const int requiredInliers) {
        mRequiredInliers = requiredInliers;
    }

    bool getBestModel(LinearModel& bestLinearModel);
    //bool run();

    void dump(const vector<Point2d>& pointListF);

    bool            isMember(const Point2d& point, const vector<Point2d>& maybeInliers) const;

        bool  fitsModel(const Point2d& P, const Point2d& A, const Point2d& B) const;

    LinearModel     getModel(const Point2d& p1, const Point2d& p2) const;
    LinearModel     getModel( vector<Point2d>& observation) ;

    vector<Point2d>  getMaybeInliers() const;

    double           getModelError( const vector<Point2d>& pointList, const Point2d& A, const Point2d& B);
    double           getDistance(const Point2d& P, const Point2d& A, const Point2d& B) const;

private:



    
};

#endif // RANSAC_H
